/* 
 * File:   networkcommunication.cpp
 * Author: iezahel
 * 
 * Created on January 1, 2009, 10:32 PM
 */

#include <SDL/SDL_net.h>

#include "networkcommunication.h"

NetworkCommunication::NetworkCommunication(TCPsocket sock) {
    tcp_sock = sock;
}

NetworkCommunication::NetworkCommunication(const NetworkCommunication& orig) {
}

NetworkCommunication::~NetworkCommunication() {
}

GAME_ERROR_CODES NetworkCommunication::SendGeneralCommand(struct GameCommand* cmd) {
    assert( cmd );

    static char buf[MAX_CMD_BUF];
    int pos = 0;

    pos = Add32BitData(cmd->version, buf, pos);
    pos = Add32BitData(cmd->cmd_id, buf, pos);
    pos = Add32BitData(cmd->data_size, buf, pos);

    if (cmd->data_size > 0)
        memcpy(buf + GAME_COMMAND_HEADER_SIZE, cmd->data, cmd->data_size);

    int bytes_to_send = GAME_COMMAND_HEADER_SIZE + cmd->data_size;

    int res = SDLNet_TCP_Send(tcp_sock, buf, bytes_to_send);
    if (res < bytes_to_send) {
        printf("Error: SDLNet_TCP_Send: %s\n", SDLNet_GetError() );
        return GAME_ERROR_NETWORK_SEND;
    }

    return GAME_ERROR_NONE;
};

GAME_ERROR_CODES NetworkCommunication::SendResumeCommand() {
    GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_RESUME, 0 };

    return SendGeneralCommand(&curr_command);
}

GAME_ERROR_CODES NetworkCommunication::SendPauseCommand() {
    GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_PAUSE, 0 };

    return SendGeneralCommand(&curr_command);
}

GAME_ERROR_CODES NetworkCommunication::SendPlayerStateCommand(int velocity, int pos_y)
{
   GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_PLAYER_STATE, 0 };

   int pos = 0;
   pos = Add32BitData(velocity, curr_command.data, pos);
   pos = Add32BitData(pos_y, curr_command.data, pos);

   curr_command.data_size = pos;

   return SendGeneralCommand(&curr_command);
}

GAME_ERROR_CODES NetworkCommunication::SendBallStateCommand(int velocity_x, int velocity_y, int pos_x, int pos_y)
{
   GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_BALL_STATE, 0 };

   //if (rand() % 30 == 0) SDL_Delay(rand() % 50);
   
   int pos = 0;
   pos = Add32BitData(velocity_x, curr_command.data, pos);
   pos = Add32BitData(velocity_y, curr_command.data, pos);
   pos = Add32BitData(pos_x, curr_command.data, pos);
   pos = Add32BitData(pos_y, curr_command.data, pos);

   curr_command.data_size = pos;

   return SendGeneralCommand(&curr_command);
}

/*
 * Send the initial game params.
 * This is the first GAME_COMMAND, sent by the server, and
 * the client should wait for it before creating its screen.
 *
 * @param position: 0/1 -> server is on the left/right side of the screen.
 * @param width, height -> the width and height of the screen.
 * @param ball_speed -> the speed of the ball (in pixels per second).
 * @param player_speed -> the speed of the players (in pixels per second).
 *
 */
GAME_ERROR_CODES NetworkCommunication::SendInitialConfig(int position, int width, int height, 
                                                         int ball_speed, int player_speed)
{
    GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_INITIAL_CONFIG, 0};

    int pos = 0;
    pos = Add8BitData((unsigned char)position, curr_command.data, pos);
    pos = Add32BitData(width, curr_command.data, pos);
    pos = Add32BitData(height, curr_command.data, pos);
    pos = Add32BitData(ball_speed, curr_command.data, pos);
    pos = Add32BitData(player_speed, curr_command.data, pos);

    curr_command.data_size = pos;

    return SendGeneralCommand(&curr_command);
}

/*
 * This command will be sent by the player, who detects that he has missed a ball.
 * Upon receiving of this commnad, the player knows, that he has just made a point.
 */
GAME_ERROR_CODES NetworkCommunication::SendMissedBallCommand()
{
    GameCommand curr_command = {PROTOCOL_VERSION, GAME_COMMAND_MISSED_BALL, 0};

    return SendGeneralCommand(&curr_command);
}
